Créa-blog

#100JoursPourCoder
Projet Créa-code

Ressources pour développeur web

Coder une API REST en 20′ en PHP avec le framework Slim

⏱️ Temps de lecture estimé : 12 minutes
Accueil PHP 8 Coder une API REST en 20′ en PHP avec le framework Slim

Bienvenue dans ce tutoriel complet ! Vous êtes sur le point de découvrir comment créer une API REST robuste et fonctionnelle en un temps record, en utilisant le micro-framework PHP Slim.

Que vous soyez un développeur débutant qui souhaite comprendre le fonctionnement des APIs ou un professionnel expérimenté à la recherche d’une méthode rapide pour vos projets, ce guide est fait pour vous.

Nous allons parcourir ensemble toutes les étapes, de la théorie à la pratique, pour vous permettre de construire votre propre service web. Attachez vos ceintures, car nous allons vous montrer qu’il n’est pas nécessaire de passer des heures à coder pour obtenir un résultat impressionnant et performant.

Qu’est-ce qu’une API et qu’est-ce que le style REST ?

Pour bien comprendre ce que nous allons faire, commençons par démystifier ce terme technique. API signifie en anglais « Application Programming Interface », que l’on pourrait traduire par « interface de programmation d’application ».

Pour résumé simplement, une API est un contrat, une passerelle qui permet à deux applications informatiques de communiquer entre elles. Imaginez-la comme un menu de restaurant : vous (le client, une application) ne voyez pas la cuisine, mais vous pouvez commander un plat (demander une ressource) en utilisant un menu bien défini (l’API). Le cuisinier (le serveur) prépare le plat et vous le sert.

Le terme REST est l’acronyme de « Representational State Transfer ». Il ne s’agit pas d’une technologie en soi, mais d’un style d’architecture, d’un ensemble de règles et de principes à suivre pour concevoir une API.

L’idée principale est d’utiliser des URLs (adresses web) et les méthodes du protocole HTTP (comme GET, POST, PUT, DELETE) pour manipuler des ressources.

Par exemple, pour obtenir la liste des utilisateurs, vous utilisez l’URL /utilisateurs avec la méthode GET. Pour créer un nouvel utilisateur, vous utilisez la même URL mais avec la méthode POST. Ce style est apprécié pour sa simplicité, sa clarté et sa nature sans état. Chaque requête est indépendante des autres, ce qui rend l’API plus fiable et plus facile à faire évoluer.

À quoi sert une API REST ?

Les services API REST sont partout autour de vous. C’est grâce à ce modèle que votre application mobile peut se connecter à un serveur pour récupérer votre fil d’actualité, que votre site e-commerce peut se synchroniser avec le stock d’un fournisseur ou que vous pouvez vous connecter à un site tiers avec votre compte Google ou Facebook.

Concrètement, une interface API REST vous permet de découpler votre application front-end (ce que l’utilisateur voit, par exemple un site web en JavaScript) de votre back-end (le serveur et la base de données). Le front-end envoie des requêtes à l’API pour obtenir ou envoyer des données, et l’API se charge d’interagir avec la base de données ou d’autres services.

Les avantages et les limites du développement d’une API REST

L’adoption du modèle REST pour créer un service d’API présente de nombreux avantages :

  • Légèreté et Scalabilité : Le protocole HTTP est léger. L’aspect sans état des requêtes permet une grande montée en charge : vous pouvez ajouter de multiples serveurs sans complexité.
  • Simplicité : Le concept est facile à comprendre et à mettre en œuvre. L’utilisation des verbes HTTP et des URLs lisibles rend l’API facile à documenter et à utiliser.
  • Interconnectivité : Une API REST est compatible avec presque tous les langages de programmation et technologies. Que votre application cliente soit codée en JavaScript, Python, Java ou même C#, elle pourra communiquer avec votre service web.
  • Séparation des préoccupations : Ce modèle force une séparation claire entre le front-end et le back-end, ce qui facilite le travail en équipe et la maintenance.

Cependant, il existe quelques limites à prendre en compte :

  • Requêtes multiples : Pour récupérer des données complexes liées entre elles, un client peut avoir besoin de faire plusieurs requêtes à l’API, ce qui peut ralentir la communication.
  • Pas de temps réel : REST est un modèle requête-réponse. Il n’est pas adapté aux applications nécessitant un flux de données en temps réel. Pour cela, des technologies comme les WebSockets sont plus appropriées.

Pourquoi choisir le framework Slim pour votre projet ?

Maintenant que vous comprenez l’importance de l’architecture REST, il est temps de vous présenter l’outil que nous allons utiliser pour créer notre API : le framework Slim.

Slim n’est pas un framework complet comme Laravel ou Symfony. Il est ce que l’on appelle un micro-framework. Son but n’est pas de tout faire, mais de fournir une base solide et rapide pour les applications qui ont des besoins spécifiques, comme une API REST.

Ses atouts sont nombreux :

  • Légèreté et vitesse : C’est le plus gros avantage. Slim a un encombrement minimal, ce qui se traduit par des performances exceptionnelles.
  • Simplicité : Le code est clair et facile à comprendre. Il n’y a pas de configuration complexe ni de lourdeur inutile.
  • Modularité : Grâce à son système de middleware, vous pouvez ajouter des fonctionnalités (authentification, gestion des erreurs) de manière très simple, sans alourdir le cœur de l’application.

En somme, pour construire une API REST en moins de 20 minutes, il n’y a pas de meilleur allié que Slim.

Préparation de l’environnement : Ce qu’il vous faut

Avant de commencer à coder notre API REST, vous avez besoin de quelques outils essentiels sur votre ordinateur. Si vous êtes déjà un développeur PHP, vous les avez probablement déjà. Sinon, pas d’inquiétude, leur installation est simple.

Vous aurez besoin de :

  1. PHP : Une version 7.4 ou supérieure est recommandée pour utiliser Slim 4. Si vous ne l’avez pas, rendez-vous sur le site officiel de PHP pour l’installer.
  2. Composer : C’est le gestionnaire de dépendances de PHP. Il permet d’installer des bibliothèques et des frameworks, dont Slim. Il est absolument indispensable. Si vous ne l’avez pas, téléchargez-le depuis le site officiel de Composer.

Une fois que vous avez PHP et Composer installés, ouvrez simplement votre terminal ou votre invite de commande.

Étape 1 : Création et installation du projet Slim

La première chose à faire est de créer le dossier de notre projet. Vous pouvez l’appeler comme vous le souhaitez. Pour ce tutoriel, nous l’appellerons tuto-api.

mkdir tuto-api
cd tuto-api

Nous sommes maintenant à l’intérieur de notre dossier de travail. C’est ici que nous allons demander à Composer d’installer le framework Slim. Composer va non seulement télécharger Slim, mais aussi toutes les bibliothèques dont il a besoin pour fonctionner.

Maitriser les commandes du terminal.

La commande est très simple :

composer require slim/slim-skeleton

Explications de la commande :

  • composer require est la commande qui indique à Composer d’ajouter une nouvelle dépendance à notre projet.
  • slim/slim est le package principal du framework Slim.
  • slim/psr7 est un package qui fournit une implémentation des standards PSR-7 et PSR-17. Ces standards définissent comment les requêtes (request) et les réponses (response) doivent être structurées en PHP. C’est essentiel pour que notre API REST puisse communiquer correctement avec les applications clientes.

Lorsque vous lancerez cette commande, Composer va créer un dossier vendor ainsi qu’un fichier composer.json et composer.lock. Le dossier vendor contient tout le code source de Slim et de ses dépendances. C’est un dossier que vous n’aurez jamais à modifier manuellement.

Étape 2 : Création de la structure de base et du premier point d’accès

Pour que notre application fonctionne, nous avons besoin d’un point d’entrée, un fichier PHP qui va recevoir toutes les requêtes. Dans le monde du développement web, il est de bonne pratique de centraliser toutes les requêtes vers un seul et unique fichier d’index, et de stocker ce fichier dans un dossier public. Cela renforce la sécurité et la clarté de l’application.

Créez un dossier public à la racine de votre projet, puis à l’intérieur de ce dossier, créez un fichier index.php.

mkdir public
touch public/index.php

Maintenant, ouvrez ce fichier public/index.php avec votre éditeur de code et écrivez le code suivant :

Découvrez comment utiliser l’IA avec VS Code.

<?php
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;

require __DIR__ . '/../vendor/autoload.php';

$app = AppFactory::create();

$app->get('/', function (Request $request, Response $response, array $args) {
    $response->getBody()->write("Bonjour depuis votre première API REST !");
    return $response;
});

$app->run();

Décryptage du code :

  • require __DIR__ . '/../vendor/autoload.php'; : Cette ligne est essentielle. Elle charge le fichier d’autoloading de Composer. C’est grâce à lui que nous pouvons utiliser les classes de Slim sans avoir à les inclure manuellement.
  • $app = AppFactory::create(); : Cette ligne crée une instance de notre application Slim. C’est l’objet principal que nous allons utiliser pour définir nos routes et faire fonctionner notre interface API.
  • $app->get('/', function (Request $request, Response $response, array $args) { ... }); : C’est la définition de notre première route. $app->get() signifie que nous voulons gérer les requêtes HTTP de type GET (celles que votre navigateur effectue par défaut). La route / est la page d’accueil de notre point d’accès API. La fonction anonyme en paramètre contient la logique de notre route. Elle reçoit deux objets ($request et $response), essentiels pour manipuler les données.
  • $response->getBody()->write("Bonjour depuis votre première API REST !"); : Nous écrivons le contenu de notre réponse HTTP. C’est le message que l’utilisateur verra dans son navigateur.
  • return $response; : Nous renvoyons l’objet de réponse, qui est la réponse finale envoyée au client.
  • $app->run(); : Cette ligne lance l’application Slim. Elle attend une requête HTTP, la fait passer par le bon gestionnaire de route, et renvoie la réponse.

Ajustez la route sii vous développez en local avec Mamp :

$app->get('/slim/public/', function (Request $request, Response $response, array $args) {
    $response->getBody()->write("Bonjour depuis votre première API REST !");
    return $response;
});

Pour la suite du tutoriel, nous utiliserons le serveur Apache ou Nginx ouvert depuis le terminal. Cela simplifie la gestion des routes avec Slim.

Étape 3 : Lancement du serveur de développement

Pour voir le résultat de notre travail, nous allons utiliser le serveur web intégré de PHP. C’est la solution la plus simple pour démarrer sans avoir à configurer un serveur Apache ou Nginx.

Formation web et informatique - Alban Guillier - Formateur

Des formations informatique pour tous !

Débutant ou curieux ? Apprenez le développement web, le référencement, le webmarketing, la bureautique, à maîtriser vos appareils Apple et bien plus encore…

Formateur indépendant, professionnel du web depuis 2006, je vous accompagne pas à pas et en cours particulier, que vous soyez débutant ou que vous souhaitiez progresser. En visio, à votre rythme, et toujours avec pédagogie.

Découvrez mes formations Qui suis-je ?

Depuis la racine de votre projet (tuto-api), exécutez la commande suivante :

php -S localhost:8080 -t public

Explications de la commande :

  • php -S : Indique à PHP de démarrer son serveur de développement.
  • localhost:8080 : C’est l’adresse et le port sur lesquels notre serveur va écouter les requêtes. Vous pouvez choisir n’importe quel port disponible, comme 8000 ou 9000.
  • -t public : C’est une instruction cruciale. Elle indique au serveur que le « document root », c’est-à-dire le dossier d’où il doit servir les fichiers, est le dossier public que nous avons créé. Toutes les requêtes seront donc dirigées vers notre fichier index.php.

Votre terminal vous indiquera que le serveur est démarré. Ouvrez votre navigateur et rendez-vous à l’adresse http://localhost:8080. Vous devriez voir le message « Bonjour depuis votre première API REST ! ».

Félicitations ! Vous venez de créer et de tester votre premier point d’accès API en moins de 5 minutes.

Cas concret : Construire une API pour gérer des tâches

Pour rendre notre apprentissage concret, nous allons imaginer que nous devons créer une API REST pour une petite application de gestion de tâches.

Pour ne pas compliquer le tutoriel avec la gestion d’une base de données, nous allons simuler nos données avec une simple variable PHP. C’est une excellente méthode pour apprendre le fonctionnement des requêtes HTTP sans se soucier du stockage persistant.

Voici la structure de nos données, que vous pouvez ajouter en haut de votre fichier public/index.php, juste après la ligne require __DIR__ . '/../vendor/autoload.php';.

<?php
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;

require __DIR__ . '/../vendor/autoload.php';

$app = AppFactory::create();

$tasks = [
    [
        'id' => 1,
        'title' => 'Rediger le premier article de blog',
        'completed' => true
    ],
    [
        'id' => 2,
        'title' => 'Preparer le tutoriel sur Slim',
        'completed' => false
    ],
    [
        'id' => 3,
        'title' => 'Publier la nouvelle API REST',
        'completed' => false
    ]
];

$app->get('/slim/public/', function (Request $request, Response $response, array $args) {
    $response->getBody()->write("Bonjour depuis votre première API REST !");
    return $response;
});

$app->run();

Votre fichier index.php contient maintenant la variable $tasks. C’est elle qui servira de source de données pour toutes nos requêtes. Maintenant, nous allons ajouter les routes.

Créer des points d’accès pour chaque action

Une bonne interface API REST utilise les méthodes HTTP de manière sémantique. Chaque méthode correspond à une action :

  • GET : Pour lire des données.
  • POST : Pour créer des données.
  • PUT : Pour mettre à jour des données existantes.
  • DELETE : Pour supprimer des données.

Nous allons coder un point d’accès pour chacune de ces actions.

1. Lister toutes les tâches (GET /tasks)

C’est l’un des points d’accès les plus courants. Il permet de récupérer la liste de toutes les ressources.

Ajoutez cette route juste après votre première route GET /.

// Route pour récupérer toutes les tâches
$app->get('/tasks', function (Request $request, Response $response) use ($tasks) {
    // On convertit notre tableau en format JSON et on l'envoie
    $payload = json_encode($tasks);

    // On définit le bon type de contenu pour la réponse
    $response->getBody()->write($payload);
    return $response->withHeader('Content-Type', 'application/json');
});

Explication : Nous utilisons use ($tasks) dans la fonction pour lui permettre d’accéder à la variable $tasks définie à l’extérieur. La fonction json_encode() est une fonction PHP native qui transforme un tableau PHP en une chaîne de caractères au format JSON, un format standard pour les échanges de données d’une API REST.

Nous définissons également l’en-tête Content-Type de la réponse pour indiquer au client que nous renvoyons du JSON, ce qui est une bonne pratique.

Pour afficher le résultat sous forme de Json, entrez l’url suivante dans votre navigateur :

http://localhost:8080/tasks

Cela affichera :

[{"id":1,"title":"Rediger le premier article de blog","completed":true},{"id":2,"title":"Preparer le tutoriel sur Slim","completed":false},{"id":3,"title":"Publier la nouvelle API REST","completed":false}]

2. Afficher une tâche spécifique (GET /tasks/{id})

Ce point d’accès permet de récupérer une seule ressource en spécifiant son identifiant (ID).

// Route pour récupérer une tâche par son ID
$app->get('/tasks/{id}', function (Request $request, Response $response, $args) use ($tasks) {
    $taskId = $args['id'];
    $task = null;

    foreach ($tasks as $t) {
        if ($t['id'] == $taskId) {
            $task = $t;
            break;
        }
    }

    if ($task) {
        $payload = json_encode($task);
        $response->getBody()->write($payload);
        return $response->withHeader('Content-Type', 'application/json');
    } else {
        $response->getBody()->write(json_encode(['error' => 'Tâche non trouvée']));
        return $response->withStatus(404)->withHeader('Content-Type', 'application/json');
    }
});

Explication : Le segment {id} dans la route est un paramètre dynamique. Il est automatiquement récupéré et passé dans le tableau $args. Nous parcourons ensuite notre tableau de tâches pour trouver celle qui correspond à l’identifiant. Si la tâche est trouvée, nous la renvoyons au format JSON. Sinon, nous renvoyons un message d’erreur et, surtout, un code d’état HTTP 404 (« Not Found »), qui est la bonne façon de signaler à un client que la ressource n’existe pas.

Par exemple, en entrant l’url :

http://localhost:8080/tasks/2

On obtient :

{"id":2,"title":"Preparer le tutoriel sur Slim","completed":false}

3. Créer une nouvelle tâche (POST /tasks)

Ce point d’accès est utilisé pour créer une nouvelle ressource. La plupart des données sont envoyées dans le corps de la requête.

// Route pour créer une nouvelle tâche
$app->post('/tasks', function (Request $request, Response $response) use (&$tasks) {
    // On récupère le corps de la requête, qui est en JSON
    $body = $request->getBody()->getContents();
    $data = json_decode($body, true);

    if ($data && isset($data['title'])) {
        $newId = end($tasks)['id'] + 1;
        $newTask = [
            'id' => $newId,
            'title' => $data['title'],
            'completed' => false
        ];
        // On ajoute la nouvelle tâche à notre tableau de données
        $tasks[] = $newTask;

        $payload = json_encode($newTask);
        $response->getBody()->write($payload);
        return $response->withStatus(201)->withHeader('Content-Type', 'application/json');
    }

    $response->getBody()->write(json_encode(['error' => 'Données invalides']));
    return $response->withStatus(400)->withHeader('Content-Type', 'application/json');
});

Explication : Notez l’utilisation de & devant $tasks (use (&$tasks)). Cela signifie que nous passons la variable par référence, ce qui nous permet de la modifier à l’intérieur de la fonction (en y ajoutant une nouvelle tâche). La fonction json_decode()est l’inverse de json_encode() : elle transforme une chaîne JSON en un tableau PHP. Si tout est correct, nous renvoyons la nouvelle tâche avec le code de statut 201 (« Created »), qui signale au client que la ressource a été créée avec succès. En cas d’erreur, nous utilisons le code 400 (« Bad Request »).

4. Mettre à jour une tâche (PUT /tasks/{id})

Ce point d’accès permet de mettre à jour une ressource existante en envoyant toutes les données modifiées.

// Route pour mettre à jour une tâche
$app->put('/tasks/{id}', function (Request $request, Response $response, $args) use (&$tasks) {
    $taskId = $args['id'];
    $body = $request->getBody()->getContents();
    $data = json_decode($body, true);

    $found = false;
    foreach ($tasks as &$task) { // On passe par référence pour la modification
        if ($task['id'] == $taskId) {
            $task['title'] = $data['title'] ?? $task['title'];
            $task['completed'] = $data['completed'] ?? $task['completed'];
            $found = true;
            $payload = json_encode($task);
            $response->getBody()->write($payload);
            return $response->withHeader('Content-Type', 'application/json');
        }
    }

    if (!$found) {
        $response->getBody()->write(json_encode(['error' => 'Tâche non trouvée']));
        return $response->withStatus(404)->withHeader('Content-Type', 'application/json');
    }
});

Explication : Nous utilisons à nouveau la référence (&) pour pouvoir modifier directement le tableau $tasks. Nous récupérons les données envoyées et nous mettons à jour les champs de la tâche correspondante. Si la tâche n’existe pas, nous retournons une erreur 404.

5. Supprimer une tâche (DELETE /tasks/{id})

Le dernier point d’accès nous permet de supprimer une ressource.

// Route pour supprimer une tâche
$app->delete('/tasks/{id}', function (Request $request, Response $response, $args) use (&$tasks) {
    $taskId = $args['id'];
    $originalCount = count($tasks);

    // On filtre le tableau pour enlever la tâche correspondante
    $tasks = array_filter($tasks, function($task) use ($taskId) {
        return $task['id'] != $taskId;
    });

    if (count($tasks) < $originalCount) {
        return $response->withStatus(204); // Code 204 = No Content, pour une suppression réussie
    } else {
        $response->getBody()->write(json_encode(['error' => 'Tâche non trouvée']));
        return $response->withStatus(404)->withHeader('Content-Type', 'application/json');
    }
});

Explication : La fonction array_filter() est parfaite pour cette opération. Elle crée un nouveau tableau contenant tous les éléments sauf celui que nous voulons supprimer. Si la suppression a réussi, la convention d’une API REST est de renvoyer le code de statut 204 (« No Content »), car il n’y a pas de corps de réponse à envoyer.


Félicitations ! Votre API REST est désormais fonctionnelle. Vous avez créé des points d’accès qui peuvent lire, créer, mettre à jour et supprimer des données.


En suivant ce guide, vous n’avez pas seulement écrit quelques lignes de code ; vous avez acquis une compréhension solide de ce qu’est un service d’API REST, à quoi il sert, et comment le concevoir avec le framework Slim. Vous avez appris à manipuler les requêtes HTTP, à structurer une interface API et à gérer les principales opérations de gestion de données (lire, créer, mettre à jour, supprimer).

Cette nouvelle compétence est une brique essentielle dans l’architecture des applications web modernes. Que ce soit pour un site e-commerce, une application mobile, ou tout autre projet nécessitant une communication entre un client et un serveur, la conception d’une API REST est une compétence indispensable et très recherchée.

Prochaines étapes : Rendre votre API plus robuste

Ce tutoriel vous a donné les bases. Pour transformer votre projet d’apprentissage en une véritable API RESTprofessionnelle, voici les pistes que vous pouvez explorer et qui feraient d’excellents sujets d’articles pour votre blog :

  • Connexion à une vraie base de données : Le remplacement de notre tableau PHP par une base de données MySQL est l’étape la plus logique. Vous pourrez alors utiliser un système de gestion de base de données pour stocker vos informations de manière permanente. Les bibliothèques PDO ou un ORM comme Doctrine seront vos meilleurs alliés.
  • Mise en place de l’authentification : Une véritable API REST a besoin de sécurité. Vous pouvez utiliser des « middlewares » dans Slim pour mettre en place une authentification par jetons (token), comme le JWT (JSON Web Token). Cela vous permettra de vous assurer que seules les requêtes autorisées peuvent accéder aux ressources.
  • Validation des données : Avant d’insérer de nouvelles données, il est crucial de les valider. Apprenez à mettre en place un processus de vérification pour vous assurer que les données envoyées par le client sont au bon format et ne contiennent pas de menaces potentielles.
  • Gestion des erreurs avancée : Au lieu de simples messages, vous pouvez créer un gestionnaire d’erreurs plus sophistiqué qui renvoie des codes de statut HTTP et des messages clairs en cas de problème. Cela rendra votre service d’API beaucoup plus fiable pour les développeurs qui l’utiliseront.

Ce tutoriel touche à sa fin, mais votre voyage dans le monde du développement d’API REST ne fait que commencer. Continuez d’explorer, de coder, et surtout, n’ayez pas peur d’expérimenter. Le framework Slim est un outil puissant, et vous venez de le maîtriser.

Quizz sur l’API REST en PHP

Testez vos nouvelles connaissances acquises sur l’API REST en PHP !

Live on Twitch